import { getAppChanges } from '../applications/app';
import { toLoadPromise } from '../lifecycles/load';
import { toBootstrapPromise } from '../lifecycles/bootstrap';
import { toMountPromise } from '../lifecycles/mount';
import { toUnmountPromise } from '../lifecycles/unmount';
import { toUnloadPromise } from '../lifecycles/unload';
import { started } from '../start.js';
import { shouldBeActive } from '../applications/app.helpers';
import {  callCapturedEventListeners } from './navigation-event.js';

let appChangeUnderway = false, // app切换完成（旧app卸载完成，新app挂载完成）
  peopleWaitingOnAppChange = [] // 排队队列中的任务

export function reroute(pendingPromises = [], eventArguments) {
    if (appChangeUnderway) {
        return new Promise((resolve, reject) => {
            peopleWaitingOnAppChange.push({
                resolve,
                reject,
                eventArguments
            })
        });
    }

    const { appsToLoad, appsToMount, appsToUnmount } = getAppChanges();

    if (started) {
        appChangeUnderway = true;
        // 调用start后，根据路径，启动和挂载应用
        return performAppChanges();
    } else {
        // 第一次走这里，注册应用时，预加载应用
        return loadApps();
    }

    // 预加载应用
    async function loadApps() {
        const apps = await Promise.all(appsToLoad.map(toLoadPromise)); // toLoadPromise => 获取bootstrap, mount, unmount 方法放到app上
        // 加载后触发路由方法
        // callAllEventListeners();
    }

    // 根据路径，启动、装载应用
    async function performAppChanges() {
        // 启动逻辑
        // 卸载不需要的应用，挂载需要的应用
        let unmountPromises = appsToUnmount.map(toUnmountPromise).map(unmountPromise => unmountPromise.then(toUnloadPromise));

        // 匹配到没有加载过的应用 (加载=> 启动 => 挂载)
        const loadThenMountPromises = appsToLoad.map(async (app) => {
            app = await toLoadPromise(app);
            return tryToBootstrapAndMount(app);
        });

        // 已经加载过了的应用 (启动 => 挂载)
        const mountPromises = appsToMount.map(async (app) => {
            return tryToBootstrapAndMount(app);
        });

        // 等待先卸载完成后触发路由方法
        await Promise.all(unmountPromises); 
        callAllEventListeners();

        // 加载后触发路由方法
        await Promise.all([...loadThenMountPromises, ...mountPromises]); 
        callAllEventListeners();

        // 完成后批量处理在队列中的任务
        finishUpAndReturn();
    }
    // 完成后，批量处理队列中的任务
    function finishUpAndReturn() {
        appChangeUnderway = false;
        if (peopleWaitingOnAppChange.length > 0) {
            const nextPendingPromises = peopleWaitingOnAppChange;
            peopleWaitingOnAppChange = [];
            reroute(nextPendingPromises)
        }
    }
    // 调用路由方法
    function callAllEventListeners() {
        pendingPromises.forEach((pendingPromise) => {
            callCapturedEventListeners(pendingPromise.eventArguments);
        });
        callCapturedEventListeners(eventArguments);
    }
}


// 启动和挂载应用
async function tryToBootstrapAndMount(app) {
    if (shouldBeActive(app)) {
        app = await toBootstrapPromise(app);
        return toMountPromise(app);
    }
    return app;
}



